package com.leeoohoo.handlers;

import com.leeoohoo.base.BaseController;
import com.leeoohoo.base.BaseService;
import com.leeoohoo.base.Result;
import com.leeoohoo.error.BizError;
import com.leeoohoo.user.MyUser;
import com.leeoohoo.user.MyUserService;
import com.leeoohoo.user.dto.InsertDTO;
import com.leeoohoo.user.dto.SearchDTO;
import com.leeoohoo.user.dto.UpdatePasswordDTO;
import com.oohoo.spacestationspringbootstarter.dto.query.EQ;
import io.micrometer.common.util.StringUtils;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("user")
public class UserHandler extends BaseController<MyUser, Long, SearchDTO, InsertDTO> {


    private final MyUserService userService;

    private final ReactiveRedisTemplate<String, String> redisTemplate;


    public UserHandler(MyUserService userService,
                       ReactiveRedisTemplate<String, String> redisTemplate) {
        this.userService = userService;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Mono<Result<Void>> save(@RequestBody @Validated Mono<InsertDTO> insertDTOMono) {
        Mono<InsertDTO> map = insertDTOMono.map(it -> {
            String encode = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(it.getPassword());
            it.setPassword(encode);
            // 默认账户可用
            it.setState(15L);
            return it;
        });
        return super.save(map);
    }


    @PostMapping("updatePassword")
    public Mono<Result<Void>> updatePassword(@RequestBody @Validated Mono<UpdatePasswordDTO> updatePasswordDTOMono) {
        return updatePasswordDTOMono.map(it -> {
            Mono<String> stringMono = redisTemplate.opsForValue().get(it.getUsername());
            String block = stringMono.block();
            if (StringUtils.isNotBlank(block)) {
                throw new BizError("验证码过期");
            }
            if (!it.getValidateCode().equals(block)) {
                throw new BizError("验证码错误");
            }
            String encode = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(it.getPassword());
            this.userService.getButler().update(EQ.update(MyUser.class)
                    .set(MyUser::getPassword, encode)
                    .where()
                    .eq(MyUser::getUsername, it.getUsername()));
            return Result.success();
        });
    }


    @Override
    public BaseService<MyUser, Long> getService() {
        return userService;
    }
}
